package com.cn.jinl.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cn.jinl.api.IOrderService;
import com.cn.jinl.api.IPlanManageService;
import com.cn.jinl.dao.*;
import com.cn.jinl.domain.*;
import com.cn.jinl.utils.*;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;


@Service
public class PlanManageServiceImpl implements IPlanManageService {

    @Autowired
    private PlanManageMapper planManageMapper;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private IOrderService orderService;

    @Autowired
    private AgvMapper agvMapper;
    @Autowired
    private GenerateUUID generateUUID;
    @Autowired
    private PersonnelManagementMapper personnelManagementMapper;
    @Autowired
    private GradeValueMapper gradeValueMapper;
    @Override
    public List<PlanManage> getPlanManageList(QueryForm queryForm) throws Exception {
//        //默认查询近三个月
//        if (queryForm.getStartTime() == null || queryForm.getStartTime().isEmpty()) {
//            SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//            Calendar calendar = Calendar.getInstance();
//            // 设置endTime为当前时间
//            queryForm.setEndTime(sdf1.format(new Date()));
//            // 设置startTime为三个月前
//            calendar.add(Calendar.MONTH, -3);
//            queryForm.setStartTime(sdf.format(calendar.getTime()));
//        }
        int count = planManageMapper.selectPlanManageListCount(queryForm);
        if(count == 0){
            return Lists.newArrayList();
        }
        List<PlanManage> planManages = planManageMapper.selectPlanManageList(queryForm);
        for(PlanManage planManage : planManages){
            String completeNum = planManage.getCompleteNum();
            if(StringUtils.isNotEmpty(completeNum)){
                double num = Double.parseDouble(completeNum);
                double total = Double.parseDouble(planManage.getPeieceNum());
                if(total > 0){
                    String percent = NumberUtil.getPoint((num*100 / total),2)+"%";
                    planManage.setCompletePercent(percent);
                }
            }else {
                planManage.setCompleteNum("0.00");
                planManage.setCompletePercent("0.00%");
            }
        }
        planManages.get(0).setCount(count);
        return planManages;
    }

    @Override
    public Map<String, List<PlanManage>> getPlanManageMapList() throws Exception {
        Map<String,List<PlanManage>> procMap = Maps.newLinkedHashMap();
        List<PlanManage> planManages = planManageMapper.selectAllPlanManageList(new QueryForm());
        procMap.put("单支连排",Lists.<PlanManage>newLinkedList());
        procMap.put("多支",Lists.<PlanManage>newLinkedList());
        procMap.put("伸缩",Lists.<PlanManage>newLinkedList());
        procMap.put("U型",Lists.<PlanManage>newLinkedList());
        for(PlanManage planManage:planManages){
            if(procMap.containsKey(planManage.getItemTypeId())){
                procMap.get(planManage.getItemTypeId()).add(planManage);
            }
        }
        return procMap;
    }

    @Override
    public PlanManage getPlanManageById(String planId) throws Exception {
        PlanManage planManage =  planManageMapper.selectPlanById(planId);
        return planManage;
    }

    @Override
    public PlanManage getPlanByOrderId(String orderId) throws Exception {
        return planManageMapper.selectPlanByOrderId(orderId);
    }

    @Override
    public List<PlanOrder> getPlanOrders(String planId) throws Exception {
        if(StringUtils.isEmpty(planId)){
            return Lists.newArrayList();
        }
        return planManageMapper.selectPlanOrderByPlanId(planId);
    }

    @Override
    public List<PlanManage> getUPlanManages(QueryForm queryForm) throws Exception {
        Map<String,String> reflectMap = Maps.newHashMap();
        reflectMap.put("普直","单支连排");
//        reflectMap.put("普直","多支");
        reflectMap.put("伸直","伸缩");
        reflectMap.put("U直","U型");
        List<PlanManage> results = Lists.newArrayList();
        List<PlanManage> planManages = planManageMapper.selectAllPlanManageList(queryForm);
        String queryName = queryForm.getItemName();
        String mappedType = reflectMap.get(queryName);
        for(PlanManage planManage:planManages){
            String itemTypeId = planManage.getItemTypeId();
            if(StringUtils.equals(mappedType, itemTypeId)){
                results.add(planManage);
            }
            else if(StringUtils.equals("普直", queryName) && StringUtils.equals("多支", itemTypeId)){
                results.add(planManage);
            }
        }
        return results;
    }



    @Override
    public String addBatchPlanManage(List<PlanManage> planManages) throws Exception {
        return null;
    }

    @Override
    public String addPlanManage(PlanManage planManage) throws Exception {
        List<PlanOrder> planOrders = planManage.getPlanOrders();
        String planType = planManage.getPlanType();
        if(StringUtils.equals("1",planType)&&CollectionUtils.isEmpty(planOrders)){
            return "参数异常！";
        }
        List<String> ids = Lists.newArrayList();
        if(StringUtils.equals("1",planType)){
            for(PlanOrder planOrder :planOrders){
                ids.add(planOrder.getOrderId());
            }
            OrderExample example = new OrderExample();
            example.createCriteria().andStatusEqualTo(Constants.NORMAL_STATUS).andIdIn(ids);
            List<Order> exists = orderMapper.selectByExample(example);
            if(exists.size()!= ids.size()){
                return "订单存在异常！";
            }
            String gradeValue = exists.get(0).getGradeValue();
            for(Order order :exists){
                if(!StringUtils.equals(gradeValue,order.getGradeValue())){
                    return "存在规格不同的订单！";
                }
                if(!StringUtils.equals(order.getOrderStatus(),"3")){
                    return "订单状态异常，无法立即排产！";
                }
            }

        }

        String yearMothDay = generateUUID.getYearStr();
        String key = "plan"+yearMothDay;
        String id = CommonUtil.generateRandomNum("plan_");
        int num = generateUUID.getNumberFlag(key);
        String code = "JH"+yearMothDay+generateUUID.getTwoNumStr(num);
        planManage.setPlanCode(code);
        planManage.setId(id);

        if(StringUtils.equals("1",planType)){
            for(PlanOrder planOrder :planOrders){
                planOrder.setPlanId(id);
            }
        }

        int count = planManageMapper.insertSelective(planManage);
        if(count > 0 && StringUtils.equals("1",planType)){
            String resp = orderService.updateOrderPC(ids);
            if(StringUtils.isNotEmpty(resp)){
                throw new Exception(resp);
            }
            count = planManageMapper.batchInsertPlanOrders(planOrders);
            if (count < 0){
                throw new Exception("插入计划异常！");
            }
        }
        return CommonUtil.outStr(count);
    }

    @Override
    public String updatePlanManage(PlanManage planManage) throws Exception {
        String id = planManage.getId();
        if(StringUtils.isEmpty(id)){
            return "缺少主键！";
        }
        PlanManage exist = planManageMapper.selectPlanById(id);
        if(null == exist){
            return "计划不存在！";
        }

        if(!StringUtils.equals(exist.getPlanStatus(),"1")){
            return "计划不在待生产状态！";
        }

        PlanManage update = new PlanManage();
        update.setCompleteTime(planManage.getCompleteTime());
        update.setGradeValue(planManage.getGradeValue());
        update.setPlanName(planManage.getPlanName());
        update.setItemTypeId(planManage.getItemTypeId());
        update.setThNumber(planManage.getThNumber());
        update.setPeieceNum(planManage.getPeieceNum());
        double totalNum = Double.parseDouble(planManage.getThNumber())*Double.parseDouble(planManage.getPeieceNum());
        update.setTotalNum(NumberUtil.getPoint(totalNum,4));
        PlanManageExample example = new PlanManageExample();
        example.createCriteria().andIdEqualTo(id);
        int count = planManageMapper.updateByExampleSelective(update,example);
        return CommonUtil.outStr(count);
    }

    @Override
    public List<String> getOrderIdsBtPlanIds(List<String> planIds) throws Exception {
        if(CollectionUtils.isEmpty(planIds)){
            return Lists.newArrayList();
        }
        return planManageMapper.selectOrderIdsByPlanIds(planIds);
    }

    @Override
    public String updatePlanManageStatus(List<String> ids,String status) throws Exception {
        if(CollectionUtils.isEmpty(ids)||StringUtils.isEmpty(status)){
            return "参数异常！";
        }
        PlanManageExample example = new PlanManageExample();
        example.createCriteria().andIdIn(ids);
        PlanManage update = new PlanManage();
        update.setPlanStatus(status);
        int count = planManageMapper.updateByExampleSelective(update,example);
        return CommonUtil.outStr(count);
    }

    @Override
    public String updatePlanManageStatus(String id, String status) throws Exception {
        if(StringUtils.isEmpty(id)||StringUtils.isEmpty(status)){
            return "参数异常！";
        }
        PlanManageExample example = new PlanManageExample();
        example.createCriteria().andIdEqualTo(id);
        PlanManage update = new PlanManage();
        update.setPlanStatus(status);
        int count = planManageMapper.updateByExampleSelective(update,example);
        return CommonUtil.outStr(count);
    }

    @Override
    public String updatePlanManageTaskCount(String planId, double addCount,String planStatus) throws Exception {
        if(StringUtils.isEmpty(planId)){
            return "参数异常！";
        }
        PlanManage update = new PlanManage();
        update.setAddCount(addCount);
        update.setId(planId);
        if(StringUtils.isNotEmpty(planStatus)){
            update.setPlanStatus(planStatus);
        }
        int count = planManageMapper.updatePlanCompleteNum(update);
        return CommonUtil.outStr(count);
    }

    @Override
    public List<PlanManage> getSelectPlanManages(String type) throws Exception {
        PlanManageExample example = new PlanManageExample();
        example.createCriteria().andStatusEqualTo(Constants.NORMAL_STATUS).andPlanStatusEqualTo("2").andItemTypeIdEqualTo(type);
        List<PlanManage> planManages = planManageMapper.selectByExample(example);
        return planManages;
    }

    @Override
    public String updateCompletePlanManage(String planId) throws Exception {
        PlanManage exist = planManageMapper.selectPlanById(planId);
        if(null == exist){
            return "计划不存在！";
        }

        if(!StringUtils.equals(exist.getPlanStatus(),"2")){
            return "计划不在生产状态！";
        }
        PlanManageExample example = new PlanManageExample();
        example.createCriteria().andIdEqualTo(planId);
        PlanManage update = new PlanManage();
        update.setPlanStatus("3");
        int count = planManageMapper.updateByExampleSelective(update,example);
        if(count < 1){
            return "更新计划异常！";
        }
        if(StringUtils.equals(exist.getPlanType(),"1")){
            String resp = orderService.updateOrderCompletePlanStatus(planId);
            if(StringUtils.isNotEmpty(resp)){
                throw new Exception(resp);
            }
        }
        return CommonUtil.outStr(count);
    }

    @Override
    public Map<String, String> getFirstPlanManageInfo() throws Exception {
        PlanManageExample example = new PlanManageExample();
        example.createCriteria().andStatusEqualTo(Constants.NORMAL_STATUS);
        List<PlanManage> planManages = planManageMapper.selectByExample(example);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy");
        String year = simpleDateFormat.format(new Date());
        String yearDay = year+"-01-01 00:00:00";
        simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date yearTime = simpleDateFormat.parse(yearDay);
        Long time = yearTime.getTime();

        Set<String> itemTypeSet = new HashSet<>();
        Set<String> gradeSet = new HashSet<>();
        double total = 0.0;
        int boxs = 0;
        for(PlanManage planManage:planManages){
            itemTypeSet.add(planManage.getItemTypeId());
            gradeSet.add(planManage.getGradeValue());
            if(planManage.getCreateTime().getTime() >= time){
                total+= Double.parseDouble(planManage.getTotalNum());
                boxs += Integer.parseInt(planManage.getPeieceNum());
            }
        }
        //人均产量
        //试用在职+合格在职总数
        int zaiZhi = personnelManagementMapper.countZaiZhi();
        //本年万支合计/试用在职+合格在职总数
        double perCapita = zaiZhi == 0 ? 0.0 : total / zaiZhi;
        Map<String, String> result = Maps.newHashMap();
        result.put("total",total+"");
        result.put("boxs",boxs+"");
        result.put("itemType",itemTypeSet.size()+"");
        result.put("grade",gradeSet.size()+"");
        result.put("perCapita", String.format("%.2f", perCapita));
        return result;
    }

    @Override
    public String callAgv(String taskCode,String point) throws Exception {
        JSONObject params = new JSONObject();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time = simpleDateFormat.format(new Date());
        //自动生成的id
        params.put("reqCode", CommonUtil.generateRandomNum("Agv-"));
        //绑定金利系统的编码
        params.put("taskCode", taskCode);
        if (StringUtils.isNotEmpty(taskCode)){
            Agv agv = new Agv();
            agv.setId(CommonUtil.generateRandomNum("Agv-"));
            agv.setTaskCode(taskCode);
            agv.setPoint(point);
            agv.setStatus("0");
            agv.setStartTime(time);
            int count = agvMapper.insertSelective(agv);
            if (count < 1) {
                throw new Exception("新增失败！");
            }else {
                //绑定现场的模版类型
                params.put("taskTyp", "test");
                JSONArray postions = new JSONArray();
                //获取现场的点位，按照模版来定义的点位，可能需要7个点位
                JSONObject postion = new JSONObject();
                //上料点1
                postion.put("positionCode", "S1");
                postion.put("type", "00");
                postions.add(postion);
                //上料点2
                JSONObject postion2 = new JSONObject();
                postion2.put("positionCode", "S2");
                postion2.put("type", "00");
                postions.add(postion2);
                //上料点3
                JSONObject postion3 = new JSONObject();
                postion3.put("positionCode", "S3");
                postion3.put("type", "00");
                postions.add(postion3);
                //下料点1
                JSONObject xlPostion1 = new JSONObject();
                xlPostion1.put("positionCode", "X1");
                xlPostion1.put("type", "00");
                postions.add(xlPostion1);

                //下料点2
                JSONObject xlPostion2 = new JSONObject();
                xlPostion2.put("positionCode", "X2");
                xlPostion2.put("type", "00");
                postions.add(xlPostion2);
                //下料点3
                JSONObject xlPostion3 = new JSONObject();
                xlPostion3.put("positionCode", "X3");
                xlPostion3.put("type", "00");
                postions.add(xlPostion3);
                //下料点4
                JSONObject xlPostion4 = new JSONObject();
                xlPostion4.put("positionCode", "X4");
                xlPostion4.put("type", "00");
                postions.add(xlPostion4);

                params.put("positionCodePath", postions);
                String dataUrl = "http://192.168.1.171:8181/rcms/hikRpcService/genAgvSchedulingTask";
                String response = doPost(dataUrl,params.toJSONString());
                if (response != null && !response.isEmpty()) {
                    return "调用异常！";
                }
            }
        }

        return null;
    }

    @Override
    public String continueAgv(String taskCode) throws Exception {
        JSONObject params = new JSONObject();
        params.put("reqCode", CommonUtil.generateRandomNum("Agv-"));
        params.put("taskCode", taskCode);
        String dataUrl = "http://192.168.1.171:8181/rcms/hikRpcService/continueTask";
        String response = doPost(dataUrl,params.toJSONString());
        if (response != null && !response.isEmpty()) {
            return "继续调用异常！";
        }
        return null;
    }

    @Override
    public String agvCallback(String method, String taskCode) throws Exception {
        Map<String, String> methodToPointMap = new HashMap<>();
        methodToPointMap.put("S1", "S1");
        methodToPointMap.put("S2", "S2");
        methodToPointMap.put("S3", "S3");
        methodToPointMap.put("X1", "X1");
        methodToPointMap.put("X2", "X2");
        methodToPointMap.put("X3", "X3");
        methodToPointMap.put("X4", "X4");
        String point = methodToPointMap.get(method);
        if (point == null) {
            throw new Exception("不存在的点位：" + method);
        }
        Agv agv = new Agv();
        if (point.equals("X4")){
        agv.setStatus("1");
        }
        agv.setPoint(point);
        AgvExample example = new AgvExample();
        example.createCriteria().andTaskCodeEqualTo(taskCode);

        int count = agvMapper.updateByExampleSelective(agv, example);

        if (count < 1) {
            throw new Exception("更新失败！");
        }
        return "更新成功";
    }

    @Override
    public Agv getAgvPoint() throws Exception {
        AgvExample example = new AgvExample();
        example.createCriteria().andStatusEqualTo("0");
        List<Agv> agvs = agvMapper.selectByExample(example);
        if (agvs.size() > 0){
            return agvs.get(0);
        }
        return null;
    }

    @Override
    public String addAgv(String jsonStr) throws Exception {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time = simpleDateFormat.format(new Date());
        JSONObject obj = JSONObject.parseObject(jsonStr);
        Agv agv = new Agv();
        agv.setTaskCode(obj.getString("taskCode"));
        agv.setPoint("S0");//因为在S1的点位上需要点击两次发车按钮
        agv.setStatus("0");
        agv.setStartTime(time);
        int count = agvMapper.insertSelective(agv);

        if (count < 1) {
            throw new Exception("新增失败！");
        }
        return CommonUtil.outStr(count);
    }

    @Override
    public String updateAgv(String jsonStr) throws Exception {
        JSONObject obj = JSONObject.parseObject(jsonStr);
        String taskCode = obj.getString("taskCode");
        // 点位数组
        String[] point = {"S0", "S1", "S2", "S3", "X1", "X2", "X3", "X4"};
        AgvExample selectExample = new AgvExample();
        selectExample.createCriteria().andTaskCodeEqualTo(taskCode).andStatusEqualTo(Constants.NORMAL_STATUS);
        List<Agv> agvList = agvMapper.selectByExample(selectExample);
        if (agvList.isEmpty()) {
            return CommonUtil.outStr(0);
        }
        Agv agv = agvList.get(0);
        String point1 = agv.getPoint();
        // 当前点位在数组中的索引
        int index = Arrays.asList(point).indexOf(point1);
        if (index == -1) {
            throw new Exception("当前点位不存在");
        }
        String nextPoint;
        String newStatus = Constants.NORMAL_STATUS;
        if (index == point.length - 1) { // 如果到达X4
            nextPoint = point[index];
            newStatus = "1";
        } else {
            nextPoint = point[index + 1]; // 下一个点位
        }
        Agv updateAgv = new Agv();
        updateAgv.setPoint(nextPoint);
        updateAgv.setStatus(newStatus);
        AgvExample updateExample = new AgvExample();
        updateExample.createCriteria().andTaskCodeEqualTo(taskCode).andStatusEqualTo(Constants.NORMAL_STATUS).andPointEqualTo(point1);
        int count = agvMapper.updateByExampleSelective(updateAgv, updateExample);

        return CommonUtil.outStr(count);
    }

    @Override
    public Map<String, String> getPlanAnalysisList(QueryForm queryForm) throws Exception {
        Map<String, String> planAnalysis = new HashMap<>();

        // 订单完成率计算
        queryForm.setPlanType("1");
        queryForm.setPlanStatus("3");
        List<PlanManage> planManages = planManageMapper.selectPlanManageList1(queryForm);
        double orderTotalPlan = 0.0;
        double orderTotalComplete = 0.0;

        for (PlanManage planManage : planManages) {
                // 获取已完成万支 = completeNum * thNumber
                double completeNum = Double.parseDouble(planManage.getCompleteNum());
                double thNumber = Double.parseDouble(planManage.getThNumber());
                double completeAmount = completeNum * thNumber;

                // 获取计划万支
                double totalNum = Double.parseDouble(planManage.getTotalNum());
                // 累加值
                orderTotalPlan += totalNum;
                orderTotalComplete += completeAmount;
        }

        // 计算订单完成率
        double orderCompletionRate = 0.0;
        if (orderTotalPlan > 0) {
            orderCompletionRate = (orderTotalComplete / orderTotalPlan) * 100;
        }

        // 备货完成率计算
        queryForm.setPlanType("2");
        queryForm.setPlanStatus("3");
        List<PlanManage> planManages2 = planManageMapper.selectPlanManageList1(queryForm);
        double stockTotalPlan = 0.0;
        double stockTotalComplete = 0.0;

        for (PlanManage planManage : planManages2) {

                // 获取已完成万支 = completeNum * thNumber
                double completeNum = Double.parseDouble(planManage.getCompleteNum());
                double thNumber = Double.parseDouble(planManage.getThNumber());
                double completeAmount = completeNum * thNumber;

                // 获取计划万支
                double totalNum = Double.parseDouble(planManage.getTotalNum());

                // 累加值
                stockTotalPlan += totalNum;
                stockTotalComplete += completeAmount;
        }

        // 计算备货完成率
        double stockCompletionRate = 0.0;
        if (stockTotalPlan > 0) {
            stockCompletionRate = (stockTotalComplete / stockTotalPlan) * 100;
        }

        // 将结果放入Map
        planAnalysis.put("orderTotalPlan", String.format("%.4f", orderTotalPlan));
        planAnalysis.put("orderTotalComplete", String.format("%.4f", orderTotalComplete));
        planAnalysis.put("orderCompletionRate", String.format("%.2f%%", orderCompletionRate));

        planAnalysis.put("stockTotalPlan", String.format("%.4f", stockTotalPlan));
        planAnalysis.put("stockTotalComplete", String.format("%.4f", stockTotalComplete));
        planAnalysis.put("stockCompletionRate", String.format("%.2f%%", stockCompletionRate));

        return planAnalysis;
    }

    @Override
    public List<GradeValue> getGradeValueByName(QueryForm queryForm) throws Exception {
        List<GradeValue> gradeValues = gradeValueMapper.getGradeValueByName(queryForm.getName());
        return gradeValues;
    }


    public static String doPost(String httpurl, String jsonData) {
        HttpURLConnection connection = null;
        OutputStream os = null;
        BufferedReader br = null;
        String result = null; // 返回结果字符串
        try {
            // 创建远程url连接对象
            URL url = new URL(httpurl);
            // 通过远程url连接对象打开一个连接，强转成httpURLConnection类
            connection = (HttpURLConnection) url.openConnection();
            // 设置连接方式：post
            connection.setRequestMethod("POST");
            // 设置请求头
            connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
            // 设置连接主机服务器的超时时间：15000毫秒
            connection.setConnectTimeout(2000);
            // 设置读取远程返回的数据时间：60000毫秒
            connection.setReadTimeout(60000);
            // 设置允许输出
            connection.setDoOutput(true);
            // 发送请求
            connection.connect();
            // 写入请求体
            os = connection.getOutputStream();
            os.write(jsonData.getBytes(StandardCharsets.UTF_8));
            os.flush();

            // 判断响应码
            if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                // 通过connection连接，获取输入流
                br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
                // 存放数据
                StringBuffer sbf = new StringBuffer();
                String temp = null;
                while ((temp = br.readLine()) != null) {
                    sbf.append(temp);
                }
                result = sbf.toString();
            } else {
                System.out.println("请求失败，HTTP 状态码：" + connection.getResponseCode());
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null) {
                connection.disconnect();
            }
        }
        return result;
    }

}
